package compoundDB.gui;

import java.util.ArrayList;
import java.util.List;

import javax.swing.table.AbstractTableModel;

@SuppressWarnings("serial")
class ResultsTableModel extends AbstractTableModel
{

	private int m_indexStart;
	private int m_entriesPerPageIdeal;
	private int m_entriesPerPageActual;// how manys actually displayed
	private Object[][] m_data;// data that the table displays(takes from
	// dataFull)
	private String[] m_columnNames;
	private Object[][] m_dataFull;

	public int getEntriesPerPageIdeal()
	{
		return m_entriesPerPageIdeal;
	}

	public void setEntriesPerPageIdeal(int entriesPerPage)
	{
		saveData();
		this.m_entriesPerPageIdeal = entriesPerPage;
		this.displayThisPage();
	}

	public ResultsTableModel(String[] columnHeadings, Object[][] dataResults)
	{
		setUp(columnHeadings);
		SetData(dataResults);
	}

	public ResultsTableModel(String[] columnHeadings)
	{
		setUp(columnHeadings);
		Object[][] temp = new Object[1][columnHeadings.length];
		for (int ix = 0; ix < m_columnNames.length; ix++)
		{
			temp[0][ix] = "";
		}
		this.SetData(temp);
		displayThisPage();
	}

	public List<Integer> getSelectedCompounds()
	{
		saveData();
		List<Integer> list = new ArrayList<Integer>();
		for (int i = 0; i < m_dataFull.length; i++)
		{
			if (m_dataFull[i][0].equals(true))
			{
				list.add(i);
			}
		}
		return list;
	}

	public void deleteCompound(List<Long> guids)
	{
		for (int i1 = 0; i1 < guids.size(); i1++)
		{
			int i2;
			for (i2 = 0; i2 < m_dataFull.length; i2++)
			{
				if (guids.get(i1) == (Long.parseLong(m_dataFull[i2][1].toString())))
				{
					break;
				}
			}
			if (i2 <= m_dataFull.length)
			{
				Object[][] temp = new Object[m_dataFull.length - 1][m_dataFull[0].length];
				for (int i3 = 0; i3 < i2; i3++)
				{
					temp[i3] = m_dataFull[i3];
				}
				for (int i3 = i2; i3 < m_dataFull.length - 1; i3++)
				{
					temp[i3] = m_dataFull[i3 + 1];
				}
				m_dataFull = temp;
			}
		}
		displayThisPage();
	}

	public void SetData(Object[][] dataResults)
	{
		m_dataFull = null;
		m_data = null;

		m_dataFull = dataResults;
		m_indexStart = 0;
		this.displayThisPage();
		this.fireTableDataChanged();
	}

	public void setUp(String[] columnHeadings)
	{
		m_indexStart = 0;
		m_entriesPerPageIdeal = 20;
		m_columnNames = columnHeadings;
	}

	public void saveData()
	{
		for (int iy = 0; iy < m_entriesPerPageActual; iy++)
		{
			for (int ix = 0; ix < m_columnNames.length; ix++)
			{
				m_dataFull[iy + m_indexStart][ix] = m_data[iy][ix];
			}
		}
	}

	public void displayThisPage()
	{
		m_entriesPerPageActual = m_entriesPerPageIdeal;
		if (m_entriesPerPageActual > m_dataFull.length - m_indexStart)
		{
			m_entriesPerPageActual = m_dataFull.length - m_indexStart;
		}
		m_data = new Object[m_entriesPerPageActual][m_columnNames.length];

		for (int iy = 0; iy < m_entriesPerPageActual; iy++)
		{
			for (int ix = 0; ix < m_columnNames.length; ix++)
			{
				m_data[iy][ix] = m_dataFull[iy + m_indexStart][ix];
			}
		}
		this.fireTableDataChanged();
	}

	public void displayNextPage()
	{
		saveData();
		if (m_entriesPerPageIdeal >= m_dataFull.length - m_indexStart)
		{
			return;
		}
		m_indexStart += m_entriesPerPageIdeal;
		this.displayThisPage();
	}

	public void displayPrevPage()
	{
		saveData();
		if (m_indexStart == 0)
		{
			return;
		}
		if (m_indexStart < m_entriesPerPageIdeal)
		{
			m_indexStart = 0;
		}
		else
		{
			m_indexStart -= m_entriesPerPageIdeal;
		}
		this.displayThisPage();
	}

	@Override
	public int getColumnCount()
	{
		return m_columnNames.length;
	}

	public void setRow(int row, Object[] compound)
	{
		m_dataFull[row] = compound;
		this.displayThisPage();
	}

	@Override
	public int getRowCount()
	{
		return m_data.length;
	}

	@Override
	public String getColumnName(int col)
	{
		return m_columnNames[col];
	}

	@Override
	public Object getValueAt(int row, int col)
	{
		try
		{
			return m_data[row][col];
		}
		catch (Exception e)
		{

			e.printStackTrace();
		}
		return null;
	}

	/*
	 * JTable uses this method to determine the default renderer/ editor for
	 * each cell. If we didn't implement this method, then the last column would
	 * contain text ("true"/"false"), rather than a check box.
	 */
	@Override
	public Class<?> getColumnClass(int c)
	{
		for (int i = 0; i < getRowCount(); i++)
		{
			if (getValueAt(i, c) != null)
			{
				return getValueAt(i, c).getClass();
			}
		}
		return String.class;
	}

	/*
	 * Don't need to implement this method unless your table's changeable.
	 */

	@Override
	public boolean isCellEditable(int row, int col)
	{
		// All data on the screen is not changeable except the first column and
		// the 5 coloumn.
		// This method is not dependent at all on the row.
		return col == 0;// the first one (aka the tick boxes)
	}

	/*
	 * Don't need to implement this method unless your table's data can change.
	 */
	@Override
	public void setValueAt(Object value, int row, int col)
	{
		m_data[row][col] = value;
		fireTableCellUpdated(row, col);
	}
}
